import json
import logging
import os
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import StreamingResponse
from fastapi.middleware.cors import CORSMiddleware
import aiofiles
from streamlit import status
from chain.parser import stream_process
from chain.prompt import TEMPLATE, SYSTEM_TEMPLATE
from model.llm import KIMI

# 配置日志
logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
logger.addHandler(logging.StreamHandler())  # 将日志输出至屏幕
init_params = {
    "api_key": "sk-0cDK3fy39sQJ3FF8JCbgbDpepgpTSZrh6qyuhkqBbjZYCmHm",
    "base_url": "https://api.moonshot.cn/v1",
}
model = KIMI(**init_params)
app = FastAPI()
DATA_FILE = "data.json"
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 允许所有来源或指定前端的 URL
    allow_credentials=True,
    allow_methods=["*"],  # 允许所有方法（GET, POST, OPTIONS 等）
    allow_headers=["*"],  # 允许所有头部
)


@app.post("/api/question")
async def question(request: Request):
    data = await request.json()
    input_text = data.get("text", "")
    if not input_text:
        return {"error": "No text provided"}
    params = {
        "model": "moonshot-v1-8k",
        "prompt": f"请结合用户的提问作出回答。提问：{input_text}",
        "system_prompt": "你叫做医疗小海，请诚实的回答用户提问的问题，如果你判断问题涉及敏感或非法信息，请回答“这个问题超出了小海的范畴，请换个问题吧。”，不要给患者推荐用药，如果涉及到用药，请替换成“结合咨询医生，结合医嘱进行用药。”，不要给患者下诊断，如果涉及诊断，请替换成“请咨询指定科室医生和具体检查获取诊断信息”",
        "temperature": 0.1,
        "stream": True,
    }
    generator = model(**params)
    return StreamingResponse(generator, media_type="text/plain")


@app.post("/api/generate")
async def generate(request: Request):
    data = await request.json()
    input_text = data.get("text", "")
    if not input_text:
        return {"error": "No text provided"}
    params = {
        "model": "moonshot-v1-8k",
        "prompt": TEMPLATE.format(input=input_text),
        "system_prompt": SYSTEM_TEMPLATE,
        "temperature": 0.1,
        "stream": True,
    }
    generator = stream_process(model(**params))
    return StreamingResponse(generator, media_type="text/plain")


@app.post("/api/feedback")
async def feedback(request: Request):
    data = await request.json()
    input_data = data.get("text", "")
    try:
        # 获取当前文件的数据
        current_data = read_data_from_file()

        # 在现有数据基础上更新
        for k, v in input_data.items():
            current_data[k] = v
            current_data[k]["status"] = "init"
        # 使用 aiofiles 异步写入文件
        async with aiofiles.open(DATA_FILE, "w", encoding="utf-8") as file:
            await file.write(
                json.dumps(current_data, ensure_ascii=False, indent=4)
            )  # 异步写入内容
        return {"message": "File written successfully", "filename": DATA_FILE}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error writing file: {str(e)}")


@app.get("/api/fetchpatient")
async def fetchpatient():
    try:
        # 获取当前文件的数据
        current_data = read_data_from_file()
        return current_data
    except Exception as e:
        return {"error": f"数据读取失败: {str(e)}"}

@app.post("/api/refreshstatus")
async def refreshstatus(request: Request):
    data = await request.json()
    input_data = data.get("text", "")
    id = input_data.get("id", "")
    status = input_data.get("status", "")
    try:
        # 获取当前文件的数据
        current_data = read_data_from_file()
        # 使用 aiofiles 异步写入文件
        current_data[id]["status"] = status
        async with aiofiles.open(DATA_FILE, "w", encoding="utf-8") as file:
            await file.write(
                json.dumps(current_data, en sure_ascii=False, indent=4)
            )  # 异步写入内容
        return {"message": "File written successfully", "filename": DATA_FILE}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Error writing file: {str(e)}")
    

# 读取当前文件内容
def read_data_from_file():
    if os.path.exists(DATA_FILE):
        try:
            with open(DATA_FILE, "r", encoding="utf-8") as file:
                data = json.load(file)
            return data
        except Exception as e:
            return {"error": f"读取文件失败: {str(e)}"}
    else:
        return {}
